# twisted imports
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.python import log
from honor import HonorLister
from orders import OrderManager
from provlist import ProvListManager
from kdlist import KingdomListManager
from nw import NWCalculator
from tracking import ProvTrackingManager
from utotime import UtoTimer
from dragon import DragonManager
from som import SomCalculator
from shout import Shouter
from links import SiteLocator


class DivBot(irc.IRCClient):
    """An IRC bot which can find provs on the honor list, and print them in IRC."""
    
    userinfo = "DivBot is created by entilzha of 9 Fates."
    fingerReply = "DivBot is created by entilzha of 9 Fates."
    versionName = "DivBot application"
    versionNum = "0.4"
    versionEnv = "some PC"
    realname = "entilzha of 9 Fates"
    nickname = "DivBot"

    def __init__(self):
        self.channels = set([])
        self.pwchans = []
        self.chans = []
        f = open('config.txt','r')
        lines = f.readlines()
        f.close()
        for l in lines:
            l = l.rstrip("\n")
            words = l.split()
            if words[0] == 'account:': 
                self.nickname = words[1]
                self.originalnick = words[1]
            if words[0] == 'password:': self.password = words[1]
            if words[0] == 'pwchan:':
                chan = words[1]
                pw = words[2]
                self.pwchans.append((chan,pw))
            if words[0] == 'chan:':
                self.chans.append(words[1])
        
        self.plugins = [HonorLister(self.msg), OrderManager(), 
                        ProvListManager(), KingdomListManager(self.msg),
                        NWCalculator(), ProvTrackingManager(self.msg),
                        UtoTimer(), SomCalculator(), Shouter(), SiteLocator()]
                        
    def userJoined(self, user, channel):
        for p in self.plugins:
            if "!orders" in p.triggers:
                result = p.command('!orders',user,channel,'!orders')
                for line in result['chanmsg']:
                    self.notice(user,line)
        
   
    def connectionMade(self):
        irc.IRCClient.connectionMade(self)

    def connectionLost(self, reason):
        irc.IRCClient.connectionLost(self, reason)
        self.channels = set([])

    # callbacks for events

    def signedOn(self):
        """Called when bot has succesfully signed on to server."""
        self.msg('NickServ', 'ghost %s %s'%(self.originalnick,self.password))
        self.setNick(self.originalnick)
        self.msg('NickServ', 'identify %s'%(self.password))
        for pwchan in self.pwchans:
            self.join(pwchan[0],pwchan[1])
        for chan in self.chans:
            self.join(chan)

    def joined(self, channel):
        """This will get called when the bot joins the channel."""
        self.channels.add(channel)

    def noticed(self, user, channel, msg):
        print user, channel, msg

    def privmsg(self, user, channel, msg):
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]

        if channel in [self.nickname, 'AUTH']:
            print user, channel, msg
            return

        firstword = msg.split(' ', 1)[0].lower()
        result = {}
        ## print firstword,user,channel,msg
        for p in self.plugins:
            if firstword in p.triggers:
                result = p.command(firstword,user,channel,msg)
                
        if result.has_key('chanmsg'):
            for line in result['chanmsg']:
                self.msg(channel, line)
        if result.has_key('usernotice'):
            for line in result['usernotice']:
                self.notice(user,line)
        if result.has_key('shoutmsg'):
            (shout, blockedchans) = result['shoutmsg']
            for chan in self.channels.difference(blockedchans):
                self.msg(chan, shout)
        
        if firstword == '!help': self.help(channel, msg)
    
    def help(self, channel, msg):
        plugins = {}
        for p in self.plugins: plugins[p.name] = p.help
        words = msg.split()
        if len(words) == 2 and words[1] in plugins.keys():
            for line in plugins[words[1]]: self.msg(channel, line)
        else:
            self.msg(channel, "Welcome to DivBot %s. The following help items are currently available:"%self.versionNum)
            for name in plugins: self.msg(channel, "%c6!help%c %s"%(03,03,name))
            

        
class DivBotFactory(protocol.ClientFactory):
    """A factory for DivBots.

    A new protocol instance will be created each time we connect to the server.
    """

    # the class of the protocol to build when new connection is made
    protocol = DivBot

    def clientConnectionLost(self, connector, reason):
        """If we get disconnected, reconnect to server."""
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "connection failed:", reason
        reactor.stop()


if __name__ == '__main__':
    import sys
    # initialize logging
    log.startLogging(sys.stdout)
    
    # create factory protocol and application
    f = DivBotFactory()

    # connect factory to this host and port
    reactor.connectTCP("irc.utonet.org", 6667, f)

    # run bot
    reactor.run()
